package org.tio.im.client;

import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.tio.core.exception.AioDecodeException;
import org.tio.im.common.Const;
import org.tio.im.common.ImStatus;
import org.tio.im.common.Protocol;
import org.tio.im.common.packets.ChatBody;
import org.tio.im.common.packets.HeartbeatBody;
import org.tio.im.common.packets.LoginReqBody;
import org.tio.im.common.session.id.impl.UUIDSessionIdGenerator;
import org.tio.utils.thread.pool.DefaultThreadFactory;

import com.alibaba.fastjson.JSON;

public class AndroidSocketTest {
	private Socket socket;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		AndroidSocketTest coxy = new AndroidSocketTest();
		coxy.send();
		
		
	}

	public AndroidSocketTest() {
		try {
			// socket = new Socket("192.168.1.135",Const.SERVER_PORT);
			socket = new Socket("120.78.77.215", 39683);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	static int HEADER_LENGHT = 7;

	private static ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;

	public static byte[] encode(byte[] body, byte cmdByte) {
		int bodyLen = 0;
		if (body != null) {
			bodyLen = body.length;
		}
		// bytebuffer的总长度是 = 消息头的长度 + 消息体的长度
		int allLen = HEADER_LENGHT + bodyLen;
		// 创建一个新的bytebuffer
		ByteBuffer buffer = ByteBuffer.allocate(allLen);
		// 设置字节序
		buffer.order(byteOrder);
		byte versionByte = 1;
		byte marskByte = 0;
		buffer.put(versionByte);
		buffer.put(marskByte);
		// byte cmdByte = 11;
		// byte cmdByte = 11;
		buffer.put(cmdByte);

		// 写入消息头----消息头的内容就是消息体的长度
		buffer.putInt(bodyLen);
		// 写入消息体
		if (body != null) {
			buffer.put(body);
		}
		return buffer.array();
	}
	
	public void sendPear() {
		try {		
			HeartbeatBody heartbeatBody = new HeartbeatBody();
			OutputStream oos = socket.getOutputStream();

			byte cmdByte = 13;

			byte[] pkgBody = encode(heartbeatBody.toByte(), cmdByte);

			oos.write(pkgBody);
			oos.flush();

			while (true) {
				Thread.sleep(500);
				InputStream ret = socket.getInputStream();
				try {
					byte[] versionLen = new byte[1];
					byte[] maskLen = new byte[1];
					byte[] cmdLen = new byte[1];

					// 加入报文头部分 前四位
					byte[] resLength = new byte[4];
					ret.read(versionLen);
					ret.read(maskLen);
					ret.read(cmdLen);
					ret.read(resLength);
					int resLengthInt = byteArrayToInt(resLength, 0);
					System.out.println("cmd:" + cmdLen[0] + ",resLength:" + resLengthInt);

					byte[] data = new byte[resLengthInt];

					ret.read(data);

					StringBuffer sb = new StringBuffer();
					for (byte b : data) {
						if (b > 0) {
							sb.append(b).append(",");
						}
					}
					System.out.println("数据长度:resLengthInt:" + resLengthInt + ",datalen:" + sb.length() + ",content：" + sb);
					String content = new String(data);
					System.out.println(content);
				} catch (Exception e) {

					e.printStackTrace();
				} finally {

				}

			}

			// ret.close();
			// oos.close();

			// socket.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void send() {
		try {
			/*
			 * ChatBody chatBody = new ChatBody() .setFrom("hello_client") .setTo("admin")
			 * .setMsgType("text") .setChatType(1) .setGroup_id("100")
			 * .setContent("普通Socket客户端转Ws消息测试!"); chatBody.setCmd(11);
			 */

			String token = "mini:2b31c1bcbc2f40fca1b2f074835cf961" + "_" + System.currentTimeMillis();
			// String token = "login:178cb14d1d43448e8e688076b5db19ce" + "_" +
			// System.currentTimeMillis();
			// header_token判断用户是否登录
			String loginname = AESCipher.aesCommEncrypt(token);

			Map<String, Object> map = new HashMap<String, Object>();
			map.put("shopId", "938740497175040299");
			map.put("shopName", "测试商店");
			// 房间信息
			String password = AESCipher.aesWxCommEncrypt(JSON.toJSONString(map));

			LoginReqBody chatBody = new LoginReqBody(loginname, password);

			OutputStream oos = socket.getOutputStream();

			chatBody.setId(UUIDSessionIdGenerator.instance.sessionId(null));
			byte cmdByte = 5;

			chatBody.setId(System.currentTimeMillis() + "");
			byte[] pkgBody = encode(chatBody.toByte(), cmdByte);

			oos.write(pkgBody);
			oos.flush();

			while (true) {
				Thread.sleep(500);
				InputStream ret = socket.getInputStream();
				try {
					byte[] versionLen = new byte[1];
					byte[] maskLen = new byte[1];
					byte[] cmdLen = new byte[1];

					// 加入报文头部分 前四位
					byte[] resLength = new byte[4];
					ret.read(versionLen);
					ret.read(maskLen);
					ret.read(cmdLen);
					ret.read(resLength);
					int resLengthInt = byteArrayToInt(resLength, 0);
					System.out.println("cmd:" + cmdLen[0] + ",resLength:" + resLengthInt);

					byte[] data = new byte[resLengthInt];

					ret.read(data);

					StringBuffer sb = new StringBuffer();
					for (byte b : data) {
						if (b > 0) {
							sb.append(b).append(",");
						}
					}
					System.out.println("数据长度:resLengthInt:" + resLengthInt + ",datalen:" + sb.length() + ",content：" + sb);
					String content = new String(data);
					System.out.println(content);
				} catch (Exception e) {

					e.printStackTrace();
				} finally {

				}

			}

			// ret.close();
			// oos.close();

			// socket.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static int byteArrayToInt(byte[] b, int offset) {
		int value = 0;
		for (int i = 0; i < 4; i++) {
			int shift = (4 - 1 - i) * 8;
			value += (b[i + offset] & 0x000000FF) << shift;
		}
		return value;
	}

	public static byte[] intToByteArray(int i) throws Exception {
		ByteArrayOutputStream buf = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(buf);
		out.writeInt(i);
		byte[] b = buf.toByteArray();
		out.close();
		buf.close();
		return b;
	}

	public static byte[] byteToByteArray(byte i) throws Exception {
		ByteArrayOutputStream buf = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(buf);
		out.writeByte(i);
		byte[] b = buf.toByteArray();
		out.close();
		buf.close();
		return b;
	}
}
